<html>
<head><meta charset="utf-8"><title>Deref Patterns Syntax · project-deref-patterns · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/index.html">project-deref-patterns</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html">Deref Patterns Syntax</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="235263175"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/235263175" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#235263175">(Apr 19 2021 at 23:05)</a>:</h4>
<p>I would like to start the discussion on the syntax for Deref patterns.<br>
So there has been a few different syntaxes proposed, which can be divided into:</p>
<ul>
<li>No Syntax</li>
<li>Using a sigil</li>
<li>And Using a keyword.</li>
</ul>
<p>The last option, using a keyword, would likely require reserving a keyword in a future edition (though using <code>k#</code> syntax or <code>r#$</code> syntax would be an option in earlier editions), unless we reused the existing <code>box</code> keyword from <code>box_syntax</code>. </p>
<p>Potential sigils that have been considered are a new <code>*</code> sigil, or reusing the <code>&amp;</code> sigil. The no syntax option would be nice for ergnomics, but it cannot be applicable in all cases (like with match ergonomics), so there should still be some syntax.</p>



<a name="235398850"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/235398850" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#235398850">(Apr 20 2021 at 19:12)</a>:</h4>
<p>this seems like a good topic to explore, yes</p>



<a name="235398943"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/235398943" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#235398943">(Apr 20 2021 at 19:13)</a>:</h4>
<p>One consideration: we may eventually want to permit moves out from behind the smart pointer</p>



<a name="235398980"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/235398980" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#235398980">(Apr 20 2021 at 19:13)</a>:</h4>
<p>the <code>box</code> keyword was something we intended to use at one time for this</p>



<a name="235399050"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/235399050" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#235399050">(Apr 20 2021 at 19:14)</a>:</h4>
<p>but I think that it would be very confusing to folks when used on something other than <code>Box</code></p>



<a name="244990548"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/244990548" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#244990548">(Jul 06 2021 at 02:45)</a>:</h4>
<p>I have been thinking a bit about the syntax. From Esteban's internals thread, there was a  desire to use a single keyword/sigil whatever, as opposed to using the smart pointer name (e.g, Rc for deref'ing Rc, etc). Following this line of thought, I think we want to treat all deref patterns as 'pointer-like' as opposed to 'type-like' where we do need to name the type (structs, enums). Therefore, I would like to propose that we extend the use of <code>&amp;</code> in patterns to match a 'pointer' rather than just specifically a borrowed reference. A further analogy is the <code>*</code> operator in expressions, which we use to deref any pointer, not just raw pointers.</p>



<a name="244990710"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/244990710" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#244990710">(Jul 06 2021 at 02:48)</a>:</h4>
<p>IMO, to be correct we must only consider deref patterns where the matched expression is borrowed, e.g., where <code>x: Rc&lt;Foo&gt;</code>, <code>match x</code> would only permit structural matches on <code>Rc</code>, but <code>match &amp;x</code> would permit deref patterns (this makes sense to me because the signature of <code>deref</code> takes <code>&amp;self</code>), this leaves space later to support <code>DerefMove</code></p>



<a name="244990792"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/244990792" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#244990792">(Jul 06 2021 at 02:50)</a>:</h4>
<p>Example: </p>
<div class="codehilite"><pre><span></span><code>fn proposed(a: Rc&lt;Foo&gt;) {
    match &amp;a { // : &amp;Rc&lt;Foo&gt;
        &amp;Foo::Bar =&gt; println!(&quot;bar&quot;),
        &amp;x =&gt; {} // x: Rc&lt;Foo&gt;
    }
}
</code></pre></div>



<a name="244990813"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/244990813" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#244990813">(Jul 06 2021 at 02:51)</a>:</h4>
<p>Note that the &amp; in the first pattern matches &amp; <em>and</em> causes a deref</p>



<a name="244990891"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/244990891" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#244990891">(Jul 06 2021 at 02:52)</a>:</h4>
<p>In the second pattern, we don't apply the deref rules because we don't need to.</p>



<a name="244990974"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/244990974" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#244990974">(Jul 06 2021 at 02:55)</a>:</h4>
<p>Now, consider the match ergonomics rules, I would apply those here as well. Therefore the <code>&amp;</code> is optional in many contexts, so we get:</p>
<div class="codehilite"><pre><span></span><code>fn proposed(a: Rc&lt;Foo&gt;) {
    match &amp;a { // : &amp;Rc&lt;Foo&gt;
        Foo::Bar =&gt; println!(&quot;bar&quot;),
        x =&gt; {} // x: &amp;Rc&lt;Foo&gt;
    }
}
</code></pre></div>
<p>Note that the type of <code>x</code> depends on how it is used (binding mode), but it is not really important because in most contexts, <code>&amp;Rc&lt;Foo&gt;</code> coerces to <code>&amp;Foo</code>.</p>



<a name="244991026"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/244991026" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#244991026">(Jul 06 2021 at 02:56)</a>:</h4>
<p>This syntax gives us the desirable syntax for strings, but is not quite the same as the 'no sigil' option</p>



<a name="244991399"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/244991399" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#244991399">(Jul 06 2021 at 03:05)</a>:</h4>
<p>The downside of this approach is that we can't use it on nested pointers, e.g., <code>Option&lt;Rc&lt;Foo&gt;&gt;</code>, however, in this case we can use <code>as_ref</code> to convert to <code>Option&lt;&amp;Rc&lt;Foo&gt;&gt;</code>, and when matching that we could use a pattern like <code>Some(&amp;Foo::Bar)</code>. I'm not sure if this is a good thing or a bad thing</p>



<a name="244991554"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/244991554" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#244991554">(Jul 06 2021 at 03:08)</a>:</h4>
<p>Note that this syntax does not subsume <code>box</code> patterns, and I think that is a feature, not a bug since box patterns (and * for Box) are a special case more similar to DerefMove than Deref</p>



<a name="245019623"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245019623" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245019623">(Jul 06 2021 at 10:25)</a>:</h4>
<p>So, the problem with using &amp; is that it affects existing code.</p>



<a name="245019804"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245019804" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245019804">(Jul 06 2021 at 10:27)</a>:</h4>
<p>Or.. Hm.</p>



<a name="245020060"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245020060" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245020060">(Jul 06 2021 at 10:30)</a>:</h4>
<p>I think it may not under this suggestion, but it matches deref patterns less than may be desired. There are a few cases that &amp;impl Deref&lt;Target=T&gt; doesn't coerce to &amp;T, the main one being generic contexts. Whether this is a problem since x can be explicitly be deref-borrowed, I do not know.</p>



<a name="245020350"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245020350" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245020350">(Jul 06 2021 at 10:33)</a>:</h4>
<blockquote>
<p>Note that this syntax does not subsume <code>box</code> patterns, and I think that is a feature, not a bug since box patterns (and * for Box) are a special case more similar to DerefMove than Deref</p>
</blockquote>
<p>I don't necessarily see why the syntax used couldn't cause DerefMove for Box or other types in the future. Perhaps not immediately, but my intention is that deref patterns completely replace the totally magic box patterns eventually.</p>



<a name="245107442"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245107442" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245107442">(Jul 06 2021 at 22:41)</a>:</h4>
<blockquote>
<p>&amp;impl Deref&lt;Target=T&gt; doesn't coerce to &amp;T</p>
</blockquote>
<p>could you expand on the generic case please? AIUI the signature of deref is &amp;Self -&gt; &amp;Self::Target, so that would always align with matching the reference version</p>



<a name="245107746"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245107746" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245107746">(Jul 06 2021 at 22:45)</a>:</h4>
<blockquote>
<p>I don't necessarily see why the syntax used couldn't cause DerefMove for Box or other types in the future. Perhaps not immediately, but my intention is that deref patterns completely replace the totally magic box patterns eventually.</p>
</blockquote>
<p>My assumption is that deref patterns for the borrowed and moved cases should have different syntax, otherwise we would need some magic to guess which to apply and I think that would always be unsatisfactory. We do tend to make borrowing distinct from moving in our syntax (consider <br>
the match ergonomics rules as an example, we don't do any <em>additional</em> implicit borrowing, we only apply the rules if the type of the expression being matched is already borrowed. Likewise with implicit deref coercions).</p>



<a name="245107868"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245107868" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245107868">(Jul 06 2021 at 22:46)</a>:</h4>
<p>So, I agree that  deref patterns should replace box patterns in the long term, but I don't believe they should until we have DerefMove, and this proposal leaves room for that to happen in the future because it only applies to borrowed values in the short term</p>



<a name="245108162"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245108162" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245108162">(Jul 06 2021 at 22:50)</a>:</h4>
<p>It might look like:</p>
<div class="codehilite"><pre><span></span><code>fn not_proposed_yet(a: Box&lt;bool&gt;) {
    match a {
        &amp;true =&gt; println!(&quot;t&quot;),  // &amp; cannot be elided because a is not borrowed.
        &amp;false =&gt; println!(&quot;f&quot;),
    }
}
</code></pre></div>
<p>In this case we use the (implicit for Box) DerefMove impl, and in the <code>match &amp;a</code> case we use the Deref impl</p>



<a name="245108235"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245108235" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245108235">(Jul 06 2021 at 22:51)</a>:</h4>
<p>My feeling is that we shouldn't worry too much about this up front, that is, we likely want "no syntax" similarly to match ergonomics, and there's a lot to be said for that being a big win already, even before we get into stabilization. I think lang discussions (a few months ago now) also moved towards this</p>



<a name="245108338"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245108338" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245108338">(Jul 06 2021 at 22:53)</a>:</h4>
<p>But an explicit syntax is definitely also desired, I think, so figuring that out makes sense - it just doesn't seem like the top concern at this juncture from my understanding.</p>



<a name="245108472"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245108472" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245108472">(Jul 06 2021 at 22:54)</a>:</h4>
<p>I think my proposal is pretty much the 'no syntax' proposal, but the question is precisely how that works (and how we support the borrowed vs moving versions of deref in the long term feels important to me)</p>



<a name="245108557"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245108557" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245108557">(Jul 06 2021 at 22:56)</a>:</h4>
<blockquote>
<p>it just doesn't seem like the top concern at this juncture from my understanding.</p>
</blockquote>
<p><span class="user-mention" data-user-id="116122">@simulacrum</span>  What do you think are the major concerns? From reading the comments in various places and the design doc, it seems to me that the syntax and exhaustiveness checking are the open questions.</p>



<a name="245109142"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245109142" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245109142">(Jul 06 2021 at 23:02)</a>:</h4>
<p>My impression is that there is essentially broad agreement on a limited subset for initial stabilization where exhaustiveness isn't a concern, and potentially even no need for an explicit syntax - e.g., "foo" matching for String.</p>



<a name="245109219"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245109219" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245109219">(Jul 06 2021 at 23:03)</a>:</h4>
<p>I think the open questions are around the exact behavior on capture (e.g., marching on String with a @ "foo", does that give you a: String, a: &amp;str, or a: &amp;String?)</p>



<a name="245109600"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245109600" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245109600">(Jul 06 2021 at 23:07)</a>:</h4>
<blockquote>
<p>initial stabilization</p>
</blockquote>
<p>presumably we'd want an RFC and an unstable implementation first?</p>



<a name="245109671"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245109671" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245109671">(Jul 06 2021 at 23:08)</a>:</h4>
<blockquote>
<p>I think the open questions are around the exact behavior on capture (e.g., marching on String with a @ "foo", does that give you a: String, a: &amp;str, or a: &amp;String?)</p>
</blockquote>
<p>I'll start a new thread ...</p>



<a name="245110789"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245110789" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245110789">(Jul 06 2021 at 23:24)</a>:</h4>
<p>I think the current trajectory in lang discussions <a href="https://github.com/rust-lang/lang-team/blob/master/design-meeting-minutes/2021-06-30-lang-team-projects.md">https://github.com/rust-lang/lang-team/blob/master/design-meeting-minutes/2021-06-30-lang-team-projects.md</a> (though not formally accepted) is that stuff can land as unstable in rustc for experimentation with just a project group in existence. But yeah, before we get to stabilization we'd want an RFC - it just doesn't need to cover all the possible feature area</p>



<a name="245111608"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245111608" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245111608">(Jul 06 2021 at 23:38)</a>:</h4>
<p><span aria-label="+1" class="emoji emoji-1f44d" role="img" title="+1">:+1:</span> cool!</p>



<a name="245247571"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245247571" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245247571">(Jul 07 2021 at 21:55)</a>:</h4>
<p><span class="user-mention" data-user-id="257758">@Connor Horman</span> is there a concrete proposal for any of the alternative syntaxes? I've seen a few examples in the design doc, but not a detailed proposal</p>



<a name="245248233"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245248233" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245248233">(Jul 07 2021 at 22:01)</a>:</h4>
<p>ping <span class="user-mention" data-user-id="119031">@Esteban Küber</span> any thoughts on the &amp;/no sigil proposal above? Or about the syntax in general (more recent thoughts than the internals thread)</p>



<a name="245251822"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245251822" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245251822">(Jul 07 2021 at 22:44)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256841">Nick Cameron</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax/near/245247571">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> is there a concrete proposal for any of the alternative syntaxes? I've seen a few examples in the design doc, but not a detailed proposal</p>
</blockquote>
<p>Wdym concrete proposals? The design doc lists all of the currently and previously discussed syntax for deref patterns. It has examples of each of the syntaxes being used.</p>



<a name="245260119"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245260119" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245260119">(Jul 08 2021 at 00:32)</a>:</h4>
<p>I guess discussion of pros and cons, people's preferences, analysis of edge cases or open questions. I'm basically trying to figure out how to move forward on choosing a syntax to implement</p>



<a name="245278259"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245278259" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245278259">(Jul 08 2021 at 07:00)</a>:</h4>
<p>One possibility would be to start out only supporting built-in types and only dereferencing to literals. That much doesn't need syntax.</p>



<a name="245283439"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245283439" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245283439">(Jul 08 2021 at 08:03)</a>:</h4>
<p>True, but I think in that case we'd want to think a bit about the next step in parallel with implementation, because I don't think we'd learn much from the implementation about the general case (although of  course these things are always full of surprises :-) )</p>



<a name="245368733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245368733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245368733">(Jul 08 2021 at 20:36)</a>:</h4>
<p>So thinking about the proposal to start implementing an absolutely minimal version, I think there is still the question of whether we require the matched expression to be borrowed, e.g.,</p>
<div class="codehilite"><pre><span></span><code>fn question(a: String, b: &amp;String) {
    // match 1
    match a {
        &quot;hello&quot; =&gt; {}
        _ =&gt; {}
    }
    // match 2
    match &amp;a {
        &quot;hello&quot; =&gt; {}
        _ =&gt; {}
    }
    // match 3
    match b {
        &quot;hello&quot; =&gt; {}
        _ =&gt; {}
    }
}
</code></pre></div>
<p>Match 2 and 3 have the same types but different shapes (potentially important, but I don't think it should be). In all matches the pattern has type &amp;'static str.</p>
<p>In my proposal above, match 1 would not be allowed, but matches 2 and 3 would. I think the 'pure' no sigil proposal would allow match 1 too. The reason I don't think it should is that we would have to implicitly borrow <code>a</code> to have the right type for the deref function, and because in the future where DerefMove exists, I would like to apply DerefMove in the case of match 1 and Deref in the cases of 2 and 3.</p>



<a name="245380301"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245380301" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245380301">(Jul 08 2021 at 22:33)</a>:</h4>
<blockquote>
<p>The reason I don't think it should is that we would have to implicitly borrow <code>a</code> to have the right type for the deref function,</p>
</blockquote>
<p>But match has always allowed the scrutinee to be a place expression, and won't move it out unless the match arm contains a by-move variable binding. For that reason I would expect match 1 to <em>not</em> use DerefMove because it doesn't have any by-move bindings, and indeed you can implement equivalent functionality without having to move <code>a</code> into the match.</p>



<a name="245381554"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245381554" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rpjohnst <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245381554">(Jul 08 2021 at 22:49)</a>:</h4>
<p>this case is also weird because string literals have reference type "built in"- it might be easier to work out the rules relative to something like <code>Vec&lt;u8&gt;</code> or <code>Box&lt;i32&gt;</code> first?</p>



<a name="245382765"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245382765" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245382765">(Jul 08 2021 at 23:06)</a>:</h4>
<p>I think that in the simplest, no match ergonomics mode, you should be able to use the <code>*</code> sigil to transform a pattern of type <code>T</code> to <code>U</code> where <code>T: Deref&lt;Target=U&gt;</code> (working from the outside in, i.e. if we need <code>*pat: T</code> then it suffices that <code>pat: U</code>). Whether this calls Deref or DerefMut or DerefMove is determined later by whether the binding at the end is by-move/ref/mut. So for example:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">proposal</span><span class="p">(</span><span class="n">a</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="kt">u8</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="nb">Box</span><span class="o">&lt;</span><span class="kt">u8</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">p</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// p: &amp;[u8], a is not moved</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="n">p</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// p: [u8], unsized local error</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="p">[</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// x: u8, a is not moved</span>
<span class="w">        </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">a</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: &amp;mut u8, b is mutably borrowed</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="n">a</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: u8, b would normally be moved but not in this case because u8 is copy</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="245383295"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245383295" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245383295">(Jul 08 2021 at 23:12)</a>:</h4>
<p>Regarding string weirdness, I think the easiest solution is to be able to use <code>"xyz"</code> as a pattern of type either <code>&amp;str</code> or <code>str</code>.</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">proposal2</span><span class="p">(</span><span class="n">a</span>: <span class="nb">String</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">p</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// p: &amp;str, a is not moved</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="s">"foo"</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// matching "foo" against a pattern place of type str</span>
<span class="w">        </span><span class="k">ref</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="o">*</span><span class="s">"bar"</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// x: &amp;String</span>
<span class="w">        </span><span class="o">*</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="s">"bar"</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// x: &amp;str</span>
<span class="w">        </span><span class="n">x</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="o">*</span><span class="s">"bar"</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// x: String, moves a</span>
<span class="w">         </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="o">&amp;*</span><span class="n">a</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="s">"foo"</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// matching "foo" against a pattern place of type &amp;str</span>
<span class="w">        </span><span class="o">&amp;</span><span class="s">"bar"</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// matching "bar" against a pattern place of type str</span>
<span class="w">         </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="245385391"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245385391" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245385391">(Jul 08 2021 at 23:42)</a>:</h4>
<blockquote>
<p>this case is also weird because string literals have reference type "built in"- it might be easier to work out the rules relative to something like Vec&lt;u8&gt; or Box&lt;i32&gt; first?</p>
</blockquote>
<p>Box is also weird because it has implicit/built-in move deref semantics as well as the explicit deref with borrowing semantics. Maybe Rc&lt;i32&gt; is the least weird place to start? (or Vec, though maybe the details of slice patterns will complicate that)</p>



<a name="245385870"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245385870" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245385870">(Jul 08 2021 at 23:51)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> using <code>*</code> as the sigil seems wrong to me - sigils in patterns usually deconstruct what they would construct in expressions, whereas here, the sigil would be doing  roughly the same a it does in expression context. I.e., it is going 'the wrong way round'.</p>



<a name="245385957"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245385957" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245385957">(Jul 08 2021 at 23:52)</a>:</h4>
<p>I think you can find/replace <code>&amp;</code> for <code>*</code> in the example if you want to use another sigil</p>



<a name="245386008"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386008" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386008">(Jul 08 2021 at 23:53)</a>:</h4>
<p>I am familiar with this reasoning about expression mirroring construction, but you don't use <code>&amp;</code> to build a <code>String</code>, so I have found the analogue somewhat confusing in this context</p>



<a name="245386112"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386112" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386112">(Jul 08 2021 at 23:54)</a>:</h4>
<p>I normally associate use of <code>*</code> with calls to deref, so it more naturally springs to mind</p>



<a name="245386120"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386120" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386120">(Jul 08 2021 at 23:54)</a>:</h4>
<p>Yeah, I think that using &amp; is a stretch, the intuition for me is that &amp; represents a 'pointer' in pattern context, not just a reference</p>



<a name="245386139"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386139" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386139">(Jul 08 2021 at 23:55)</a>:</h4>
<p>and it's also conveniently unused in pattern grammar</p>



<a name="245386218"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386218" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386218">(Jul 08 2021 at 23:56)</a>:</h4>
<p>I do like that it tends to produce patterns that look like <code>&amp;****(ref a)</code> which are familiar from expression context</p>



<a name="245386222"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386222" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386222">(Jul 08 2021 at 23:56)</a>:</h4>
<p>The synbtax which most conforms to current syntax, IMO, is to use the pointer name, i.e., use String to deref a String, Box to deref a Box, etc. (possibly with some other sigil or keyword to avoid ambiguity with structural matching), but there was a lot of pushback against that on the old internals thread. If we're using one sigil/keyword for all pointer-like things, then I think &amp; makes sense</p>



<a name="245386327"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386327" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386327">(Jul 08 2021 at 23:58)</a>:</h4>
<blockquote>
<p>Mario Carneiro: I do like that it tends to produce patterns that look like &amp;****(ref a) which are familiar from expression context</p>
</blockquote>
<p>IMO this violates the principal that things which look similar should be similar and things which look different should be different. Because in that pattern, &amp; and * are doing basically the same thing</p>



<a name="245386358"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386358" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386358">(Jul 08 2021 at 23:59)</a>:</h4>
<p>Is it? <code>Deref</code> coercion does not change from one pointer type to another, it changes one place type to another. <code>&amp;</code> dereferences pointers</p>



<a name="245386428"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386428" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386428">(Jul 09 2021 at 00:00)</a>:</h4>
<p>That is, <code>*</code> is being used to go from <code>String</code> to <code>str</code></p>



<a name="245386475"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386475" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386475">(Jul 09 2021 at 00:01)</a>:</h4>
<p>there aren't any references directly involved, so I don't see how <code>&amp;</code> can be made to fit</p>



<a name="245386621"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386621" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386621">(Jul 09 2021 at 00:03)</a>:</h4>
<p>If you pattern match directly on a type <code>a: T</code> with a bunch of derefs on it, you get a pattern like <code>***(ref p)</code> without the initial <code>&amp;</code>. You would only have that if you matched on <code>a: &amp;T</code></p>



<a name="245386845"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386845" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386845">(Jul 09 2021 at 00:06)</a>:</h4>
<p>Hmm, that makes sense if you read * as an operator in the pattern (like ref) rather than as constructor (using some hand wavey terminology here)</p>



<a name="245386941"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386941" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386941">(Jul 09 2021 at 00:08)</a>:</h4>
<p>Well, I don't have any strong feelings about it. Other sigils work too, and I'm mainly interested in pinning down how the nuts and bolts of the matching itself work, to assist with the implementation side</p>



<a name="245386958"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245386958" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245386958">(Jul 09 2021 at 00:09)</a>:</h4>
<p>It feels a bit weird that the deref method gives a &amp;U and we are dereferencing that implicitly, but would require the &amp; if the original type is borrowed. I see the reasoning in that we're treatingit as a place, but it sill seems odd to me, maybe I should just sit with it for a while :-)</p>



<a name="245387033"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245387033" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245387033">(Jul 09 2021 at 00:10)</a>:</h4>
<p>It's because we aren't actually calling deref; we actually don't know whether we'll be calling deref or deref_mut when we do typechecking. It's the same with regular deref coercion</p>



<a name="245387135"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245387135" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245387135">(Jul 09 2021 at 00:12)</a>:</h4>
<p>I haven't treated how match ergonomics interacts with this, or whether there should be additional match ergonomics extensions specifically for deref patterns. It would be cool to be able to insert derefs to fix type errors but I don't know how feasible that is (and it might also be tough to specify)</p>



<a name="245387625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245387625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245387625">(Jul 09 2021 at 00:22)</a>:</h4>
<p>Note: Reguardless of the syntax, an attempt to produce a by-value binding should be ill-formed except for Box (until we have DerefMove)</p>



<a name="245388290"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245388290" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245388290">(Jul 09 2021 at 00:36)</a>:</h4>
<p>Still assuming <code>*</code> as sigil: Match ergonomics ("default binding modes") are triggered when you use a struct pattern like <code>Some(x): &amp;Option&lt;T&gt;</code> (using <code>pat: T</code> to mean that <code>pat</code> is being typechecked with expected type <code>T</code>), which leads to <code>x: T [ref]</code>, where <code>[ref]</code> means that <code>x</code> will be changed to a ref binding even if the user doesn't write <code>ref x</code>.</p>
<p>Let's say that we have a goal <code>*pat: T</code>. We check that <code>T</code> has a deref to <code>U</code>. If it supports Deref but not DerefMut, we do <code>pat: U [ref]</code>, if it has DerefMut then we do <code>pat: U [ref mut]</code>, and if it has DerefMove (aka it is <code>Box&lt;U&gt;</code>) then we just check <code>pat: U</code>. Examples:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">match_ergonomics</span><span class="p">(</span><span class="n">a</span>: <span class="nb">String</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">c</span>: <span class="nb">Box</span><span class="o">&lt;</span><span class="nb">Option</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">d</span>: <span class="kp">&amp;</span><span class="nb">String</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="n">a</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: &amp;mut str</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="n">b</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// b: &amp;mut [String]</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="p">[</span><span class="n">b</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// b: &amp;mut String</span>
<span class="w">        </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="p">[</span><span class="o">*</span><span class="n">b</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="s">"foo"</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// b: &amp;mut str</span>
<span class="w">        </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// b: &amp;[String]</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="nb">Some</span><span class="p">(</span><span class="o">*</span><span class="s">"foo"</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// star is required for deref coercion, but does not move c</span>
<span class="w">        </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">*</span><span class="n">x</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// x: &amp;String because we deref'd &amp;String and ref-bound the result</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">d</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="o">**</span><span class="n">x</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// x: &amp;str</span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>I'm not sure I totally like the consequences here, and in particular it would be nice to have <code>x: &amp;str</code> in the second to last example, but <code>&amp;T</code> itself implements deref (to <code>T</code>, of course), so even though we are using a different sigil it doesn't help here to determine that we want to deref <code>T</code> and not <code>&amp;T</code></p>



<a name="245389559"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245389559" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rpjohnst <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245389559">(Jul 09 2021 at 00:58)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256841">Nick Cameron</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax/near/245386958">said</a>:</p>
<blockquote>
<p>It feels a bit weird that the deref method gives a &amp;U and we are dereferencing that implicitly, but would require the &amp; if the original type is borrowed. I see the reasoning in that we're treatingit as a place, but it sill seems odd to me, maybe I should just sit with it for a while :-)</p>
</blockquote>
<p>another case of the "treating it as a place" idea is the reasoning that led to <code>&amp;foo[i..j]</code> requiring that "extra" <code>&amp;</code>. at the time there were arguments for bare <code>foo[i..j]</code> (and also <code>foo[i]</code> for consistency, iirc?) to have reference-to-slice type, but in the end what won out was consistency with <code>foo[i]</code> being a place.</p>
<p>IOW it doesn't matter what the <code>deref</code> method (or the <code>index</code>) method returns, because the user isn't concerned with calling that method- they're using the <code>*</code>/<code>[i]</code>/deref-pattern syntax which operates on places, and the method only returns a reference because Rust doesn't have C++-style reference types for places.</p>



<a name="245389850"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245389850" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rpjohnst <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245389850">(Jul 09 2021 at 01:03)</a>:</h4>
<p>though OTOH, Rust is already in kind of a weird place with Deref- in one sense it's the overloaded <code>*</code> operator and types that implement it are just "other pointer types" alongside <code>&amp;T</code>, but in another sense things like deref coercion and binding modes mean that types like <code>String</code> or <code>Vec</code> get treated as both "fancy <code>&amp;str</code>/<code>&amp;[T]</code>" and as "owned" things, so things are fuzzy depending on context (e.g. for some <code>fn f(s: &amp;str)</code> and <code>string: String</code> you typically call it with <code>f(&amp;string)</code> -- which looks like a double indirection even though IIUC it desugars to <code>&amp;*string</code>! -- rather than <code>f(string)</code> -- a consistent number of levels of indirection -- like you would if <code>string: &amp;str</code>)</p>



<a name="245390927"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245390927" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245390927">(Jul 09 2021 at 01:26)</a>:</h4>
<blockquote>
<p>you typically call it with <code>f(&amp;string)</code> -- which looks like a double indirection even though IIUC it desugars to <code>&amp;*string</code>!</p>
</blockquote>
<p>Well, strictly speaking, it (eventually) desugars some more to <code>f(Deref::deref(&amp;string))</code>, which does actually contain a double indirection - the call to <code>deref</code> is taking a <code>&amp;String</code></p>



<a name="245390956"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245390956" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245390956">(Jul 09 2021 at 01:27)</a>:</h4>
<p>but I guess that probably optimizes away</p>



<a name="245394288"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245394288" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245394288">(Jul 09 2021 at 02:38)</a>:</h4>
<blockquote>
<p>though OTOH, Rust is already in kind of a weird place with Deref ...</p>
</blockquote>
<p>I think this weirdness comes from conflating the deref coercion rules with applying Deref::deref. Looking somewhere without potential for coercion, * strictly converts &amp;T to &amp;&lt;T as Deref&gt;::Target. Taking into account the coercion rules, the intuition is that we can implicitly convert between different forms of borrowed data, but not from owned to borrowed (or vice versa). The rules for receivers are even more flexible though.</p>



<a name="245394587"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245394587" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245394587">(Jul 09 2021 at 02:46)</a>:</h4>
<blockquote>
<p>It's because we aren't actually calling deref; we actually don't know whether we'll be calling deref or deref_mut when we do typechecking. It's the same with regular deref coercion</p>
</blockquote>
<p>I don't understand this. When doing deref coercion, we don't call deref, but we do follow the signature, e.g., we convert <code>&amp;String</code> to <code>&amp;str</code>. Coercion can also do other conversions, such as &amp;&amp; to &amp; which are not given by a Deref impl.</p>



<a name="245395129"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245395129" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245395129">(Jul 09 2021 at 02:59)</a>:</h4>
<blockquote>
<p>But match has always allowed the scrutinee to be a place expression, and won't move it out unless the match arm contains a by-move variable binding. For that reason I would expect match 1 to not use DerefMove because it doesn't have any by-move bindings, and indeed you can implement equivalent functionality without having to move a into the match.</p>
</blockquote>
<p>I'm still trying to understand this properly. AIUI, if a: String, then in match a, a is not a place expression, it's a value expression. We don't necessarily move out of a though, only if the pattern value moves it. So in a branch b =&gt; {} we would move, but in ref b =&gt; {} we'd borrow. In either case, a pattern for b must have String type.</p>



<a name="245395461"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245395461" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245395461">(Jul 09 2021 at 03:04)</a>:</h4>
<p>So, extending this to deref patterns. I'll use <code>*</code> (though I'm still not a fan) and assume that DerefMove exists, though I'm not sure it makes sense for String</p>



<a name="245395536"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245395536" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245395536">(Jul 09 2021 at 03:06)</a>:</h4>
<p>The question is should *"foo" be a valid pattern for a branch of match a (delaying variables for a minute)</p>



<a name="245395721"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245395721" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245395721">(Jul 09 2021 at 03:10)</a>:</h4>
<p>I guess one could argue that since a.deref() would give &amp;str, then it should. OTOH, Deref::deref(a) would be a type error. <code>*a</code> is OK, but requires <code>&amp;*a</code> in most contexts because str is unsized.</p>



<a name="245395842"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245395842" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245395842">(Jul 09 2021 at 03:12)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256841">Nick Cameron</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax/near/245394587">said</a>:</p>
<blockquote>
<blockquote>
<p>It's because we aren't actually calling deref; we actually don't know whether we'll be calling deref or deref_mut when we do typechecking. It's the same with regular deref coercion</p>
</blockquote>
<p>I don't understand this. When doing deref coercion, we don't call deref, but we do follow the signature, e.g., we convert <code>&amp;String</code> to <code>&amp;str</code>. Coercion can also do other conversions, such as &amp;&amp; to &amp; which are not given by a Deref impl.</p>
</blockquote>
<p>Oops, I realize I've been using the wrong word. I am talking about the use of <code>*x</code> when <code>x</code> is not a reference type, for example <code>&amp;*x</code> where <code>x: Rc&lt;u8&gt;</code>. This doesn't call deref so much as construct a place with the target type described by the deref impl; the later use of <code>&amp;</code> or <code>&amp;mut</code> is what determines whether this is eventually desugared to a call to deref or deref_mut. I will call this using the star operator for want of a better name.</p>
<p>Deref coercions are actually talking about how <code>&amp;T</code> "decays" to <code>&amp;U</code> without any syntax when typechecking demands it. In this case we could write the equivalent using the star operator as <code>&amp;**x</code>, and no fancy type mismatch repairs are needed to make this work. The examples I have given thus far haven't been using this at all, but one could potentially use the same method to remove some of the stars from the <code>match_ergonomics()</code> example.</p>



<a name="245395850"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245395850" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245395850">(Jul 09 2021 at 03:12)</a>:</h4>
<p>So here we get to an interesting intersection with the syntax: if we use <code>*</code>, then I think it makes sense to accept match a, since the behaviour matches that of the * operator (mapping to *Deref::deref(&amp;a))</p>



<a name="245395868"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245395868" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245395868">(Jul 09 2021 at 03:13)</a>:</h4>
<p>But with <code>&amp;</code> it maybe doesn't make sense because that suggests the more regular coercion site rules which don't allow the implicit borrowing</p>



<a name="245395948"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245395948" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245395948">(Jul 09 2021 at 03:15)</a>:</h4>
<blockquote>
<p>I am talking about the use of <em>x when x is not a reference type, for example &amp;</em>x where x: Rc&lt;u8&gt;. This doesn't call deref so much as construct a place with the target type described by the deref impl; the later use of &amp; or &amp;mut is what determines whether this is eventually desugared to a call to deref or deref_mut. I will call this using the star operator for want of a better name.</p>
</blockquote>
<p>I don't think that is quite accurate: see <a href="https://doc.rust-lang.org/stable/reference/expressions/operator-expr.html#the-dereference-operator">https://doc.rust-lang.org/stable/reference/expressions/operator-expr.html#the-dereference-operator</a>, "On non-pointer types *x is equivalent to *std::ops::Deref::deref(&amp;x) in an immutable place expression context and *std::ops::DerefMut::deref_mut(&amp;mut x) in a mutable place expression context."</p>



<a name="245396104"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245396104" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245396104">(Jul 09 2021 at 03:18)</a>:</h4>
<blockquote>
<p>When doing deref coercion, we don't call deref, but we do follow the signature</p>
</blockquote>
<p>To clarify this, it should read "When type checking a deref coercion, the compiler doesn't call deref, but it does follow the signature. deref <em>is</em> called at runtime"</p>



<a name="245396331"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245396331" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245396331">(Jul 09 2021 at 03:24)</a>:</h4>
<blockquote>
<p>I'm still trying to understand this properly. AIUI, if a: String, then in match a, a is not a place expression, it's a value expression. We don't necessarily move out of a though, only if the pattern value moves it.</p>
</blockquote>
<p>If it was a value expression, then we would always move out of it. For example if you have <code>a;</code> alone on a line then that would count as a use of <code>a</code> and we wouldn't be able to use it afterwards. The only reason <code>match a { _ =&gt; {} }</code> doesn't move <code>a</code> out is because it's an lvalue expression. Similarly, if <code>x: &amp;[String, 1000000]</code> then <code>match *x { _ =&gt; {} }</code> doesn't copy a million strings on the stack.</p>
<blockquote>
<p>The question is should *"foo" be a valid pattern for a branch of match a (delaying variables for a minute)</p>
</blockquote>
<p>Today that would cause a type error since <code>"foo"</code> has type <code>&amp;'static str</code>. This is a problem because we can't add more sigils to make that pattern have type <code>&amp;str</code>; it is at best a pattern of type <code>str</code> with default ref binding mode. That's why my suggestion is to just let string literals be used at type <code>str</code> too, although you still have to ref-bind them if you do something like <code>a @ "foo"</code>. The default binding mode trick should avoid having to say <code>ref a</code> explicitly in almost all cases though.</p>



<a name="245396435"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245396435" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245396435">(Jul 09 2021 at 03:27)</a>:</h4>
<blockquote>
<p>AIUI, if a: String, then in match a, a is not a place expression</p>
</blockquote>
<p>Whoops, I was being silly and misread the reference, of course a is  a place expression</p>



<a name="245396720"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245396720" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245396720">(Jul 09 2021 at 03:32)</a>:</h4>
<p>The issues with string literals not working at type <code>str</code> means that there isn't a pattern you can write in this match today to make it work:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="o">*</span><span class="s">"foo"</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// note, we are matching on something of type str</span>
<span class="w">        </span><span class="s">"foo"</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// type error</span>
<span class="w">        </span><span class="o">*</span><span class="s">"foo"</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// that's not a thing</span>
<span class="w">        </span><span class="k">ref</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="fm">matches!</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="s">"foo"</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// okay fine</span>
<span class="w">        </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="245396752"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245396752" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245396752">(Jul 09 2021 at 03:33)</a>:</h4>
<blockquote>
<p>That's why my suggestion is to just let string literals be used at type str too, although you still have to ref-bind them if you do something like a @ "foo". The default binding mode trick should avoid having to say ref a explicitly in almost all cases though.</p>
</blockquote>
<p>I agree with this. My question is if we must make the borrow explicit in the scrutinee. And I think that comes down to the syntax, if we use <code>*</code> I think that it is OK, and the pattern should have type str, which we could allow literals to match. If using &amp; then I think we should require a borrowed type</p>



<a name="245396809"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245396809" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245396809">(Jul 09 2021 at 03:34)</a>:</h4>
<p>oh right, do we want people to have to write <code>&amp;mut &amp;mut &amp;mut (ref mut a)</code>? That is really icky</p>



<a name="245396867"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245396867" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245396867">(Jul 09 2021 at 03:35)</a>:</h4>
<p>To match what?</p>



<a name="245396923"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245396923" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245396923">(Jul 09 2021 at 03:36)</a>:</h4>
<p>If we are using <code>&amp;</code> as the sigil then it seems like it implies that it is a shared reference. You can't use <code>&amp;x</code> to match on <code>&amp;mut Option&lt;T&gt;</code> after all</p>



<a name="245396959"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245396959" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245396959">(Jul 09 2021 at 03:37)</a>:</h4>
<blockquote>
<p>You can't use &amp;x to match on &amp;mut Option&lt;T&gt; after all</p>
</blockquote>
<p>IMO, this is a mistake and we could fix it as part of this work.</p>



<a name="245397042"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245397042" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245397042">(Jul 09 2021 at 03:38)</a>:</h4>
<p>and even if we say that you have to use <code>&amp;mut</code> for DerefMut patterns, what about DerefMove? <code>box</code> makes a comeback</p>



<a name="245397051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245397051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245397051">(Jul 09 2021 at 03:38)</a>:</h4>
<p>Using <code>&amp;</code> as the sigil has the mental model that <code>&amp;</code> matches any pointer-like thing in a pattern</p>



<a name="245397098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245397098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245397098">(Jul 09 2021 at 03:39)</a>:</h4>
<p>I'm pretty okay with that. My main worry is about potential for ambiguity with other things that <code>&amp;</code> does in a pattern meaning that it doesn't do what you want and you don't have alternate syntax for the right thing</p>



<a name="245397210"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245397210" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245397210">(Jul 09 2021 at 03:41)</a>:</h4>
<blockquote>
<p>what about DerefMove? </p>
</blockquote>
<p>DerefMove would be used if the scrutinee has non-reference type and the pattern variable binds by move</p>



<a name="245397301"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245397301" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245397301">(Jul 09 2021 at 03:43)</a>:</h4>
<p>I meant under the assumption that different sigils are used for the different borrowing modes because pattern constructors mirror expr constructors</p>



<a name="245397493"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245397493" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245397493">(Jul 09 2021 at 03:46)</a>:</h4>
<blockquote>
<p>My main worry is about potential for ambiguity with other things that &amp; does in a pattern meaning that it doesn't do what you want and you don't have alternate syntax for the right thing</p>
</blockquote>
<p>Yeah, so I've thought about this a bit, but I'm pretty sure I haven't exhaustively covered the cases. The simple case is say an enum Foo with a Bar variant which also implements Deref, say to str.</p>
<p>So assuming f: &amp;Foo, the following should be valid:</p>
<div class="codehilite"><pre><span></span><code>match f {
    &amp;&quot;hello&quot; =&gt; {}
    &amp;Foo::Bar =&gt; {}
    _ =&gt; {}
}
</code></pre></div>
<p>That seems OK ish since it is not ambiguous if taking types into account. If Foo derefs to itself, and you match &amp;Foo::Bar, then the compiler could either call deref or not, but it seems obvious that you wouldn't.</p>



<a name="245397573"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245397573" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245397573">(Jul 09 2021 at 03:48)</a>:</h4>
<blockquote>
<p>I meant under the assumption that different sigils are used for the different borrowing modes because pattern constructors mirror expr constructors</p>
</blockquote>
<p>Right, I'm not a fan of that assumption because IMO the logical conclusion is that we should use something like *Rc and *Box and *String, etc, which is unergonomic and boilerplatey</p>



<a name="245399052"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245399052" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245399052">(Jul 09 2021 at 04:11)</a>:</h4>
<blockquote>
<p>That seems OK ish since it is not ambiguous if taking types into account. If Foo derefs to itself, and you match &amp;Foo::Bar, then the compiler could either call deref or not, but it seems obvious that you wouldn't.</p>
</blockquote>
<p>To formalize this a bit, to make automatic deref coercions work (i.e. no syntax implicit deref), the rule would be something like: if the goal is <code>pat: T</code> and the pattern fails to typecheck at type <code>T</code>, then try <code>pat: U</code> instead (where, as ever, <code>T: Deref&lt;Target=U&gt;</code>). I'm not sure exactly how this works for deref coercions in expression position, failing to typecheck seems like a really problematic guard condition so there is probably something more constrained, but whatever they use there could also be used here</p>



<a name="245399172"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245399172" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245399172">(Jul 09 2021 at 04:13)</a>:</h4>
<p>With that rule, you could remove most of the stars in the previous examples. In particular, <code>match (x: String) { "foo" =&gt; ... }</code> works, which makes me happy</p>



<a name="245399335"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245399335" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245399335">(Jul 09 2021 at 04:16)</a>:</h4>
<blockquote>
<p>If Foo derefs to itself</p>
</blockquote>
<p><span aria-label="thinking" class="emoji emoji-1f914" role="img" title="thinking">:thinking:</span> </p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nc">Deref</span><span class="o">&lt;</span><span class="n">Target</span><span class="o">=</span><span class="n">T</span><span class="o">&gt;&gt;</span><span class="p">(</span><span class="n">x</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span>: <span class="kp">&amp;</span><span class="kt">u8</span> <span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">x</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="c1">// reached the recursion limit while auto-dereferencing `T`</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="245399412"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245399412" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245399412">(Jul 09 2021 at 04:18)</a>:</h4>
<p>Are there any types that deref to themselves? It seems like you would often stumble into recursion limits like this. I'm going to say that this is evidence that you don't have to worry about that situation</p>



<a name="245399463"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245399463" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245399463">(Jul 09 2021 at 04:19)</a>:</h4>
<blockquote>
<p>I'm not sure exactly how this works for deref coercions in expression position, failing to typecheck seems like a really problematic guard condition so there is probably something more constrained</p>
</blockquote>
<p>I believe it is not quite failure to type check. Anywhere that coercion is allowed, there is always a known 'target' type, and the compiler attempts to unify the target type and the expression type. If that fails it will apply possible coercions and try to unify again. So it's failure to unify two types, rather than failing to type check an expression.</p>



<a name="245399532"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245399532" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245399532">(Jul 09 2021 at 04:20)</a>:</h4>
<blockquote>
<p>Are there any types that deref to themselves?</p>
</blockquote>
<p>Not that I'm aware of</p>



<a name="245400113"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245400113" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245400113">(Jul 09 2021 at 04:33)</a>:</h4>
<p>I wonder if we could consider no-sigil syntax deref patterns as an extension of the match ergonomics rules? I.e., MER lets you match &amp;Foo as a Foo, then apply the binding mode rules. What if we simply extend that to letting you match T as a U if &lt;T as Deref&gt;::Target =U (plus treat string lits as str or &amp;str)? I think that is flexible and succinct. I wonder if it would look too magic?</p>



<a name="245400201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245400201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245400201">(Jul 09 2021 at 04:35)</a>:</h4>
<p>The binding mode would require the specific Deref trait, and would error if one wasn't present</p>



<a name="245400411"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245400411" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245400411">(Jul 09 2021 at 04:39)</a>:</h4>
<p>It feels like a much bigger change, and people will complain that match is getting even more magic, but honestly it feels in the right spirit - marking pointers in patterns is just boilerplate and we try hard elsewhere to eliminate the <code>&amp;**</code> kinds of type tetris programming</p>



<a name="245474202"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245474202" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rpjohnst <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245474202">(Jul 09 2021 at 17:42)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256841">Nick Cameron</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax/near/245394288">said</a>:</p>
<blockquote>
<blockquote>
<p>though OTOH, Rust is already in kind of a weird place with Deref ...</p>
</blockquote>
<p>I think this weirdness comes from conflating the deref coercion rules with applying Deref::deref. Looking somewhere without potential for coercion, * strictly converts &amp;T to &amp;&lt;T as Deref&gt;::Target.</p>
</blockquote>
<p>I don't believe this is the case, at least not syntactically- * doesn't operate on &amp;Ts but on Ts, and it converts to &lt;T as Deref&gt;::Target without the extra &amp;. <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=1cd347bd0f0516ab98d63fa71c60a4bf">For example</a> given <code>s: String</code>, <code>*s: str</code>.</p>



<a name="245474442"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245474442" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rpjohnst <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245474442">(Jul 09 2021 at 17:44)</a>:</h4>
<p>or am i misreading your comment? i guess it works if you put the * inside the &amp;, so <code>&amp;s</code> + <code>*</code> = <code>&amp;*s</code> which is of type <code>&amp;str</code></p>



<a name="245474909"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245474909" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rpjohnst <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245474909">(Jul 09 2021 at 17:46)</a>:</h4>
<p>...skimming the rest of this, i do agree that no-sigil should match the default binding rules stuff! if you have an Rc&lt;Foo&gt; and you match it with a Foo pattern then it should behave the same as if you had a &amp;Foo, and implicitly deref + switch to ref mode for inner bindings</p>



<a name="245482082"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245482082" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245482082">(Jul 09 2021 at 18:45)</a>:</h4>
<p><span class="user-mention silent" data-user-id="117495">rpjohnst</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax/near/245474909">said</a>:</p>
<blockquote>
<p>...skimming the rest of this, i do agree that no-sigil should match the default binding rules stuff! if you have an Rc&lt;Foo&gt; and you match it with a Foo pattern then it should behave the same as if you had a &amp;Foo, and implicitly deref + switch to ref mode for inner bindings</p>
</blockquote>
<p>Hmm, seems ambiguous to me: should matching <code>Vec&lt;String&gt;</code> against <code>[a, b]</code> match as <code>a: &amp;String</code>, <code>a: &amp;mut String</code>, or, when <code>Vec&lt;T&gt;: DerefMove</code>, match as <code>a: String</code>?</p>



<a name="245482320"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245482320" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245482320">(Jul 09 2021 at 18:48)</a>:</h4>
<p>I think deciding the default <code>ref</code>/<code>ref mut</code> binding mode should only be done from actual references, having it change if <code>MyType</code> decides it now wants to also implement <code>DerefMut</code> seems like a bad idea.</p>



<a name="245482958"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245482958" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> rpjohnst <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245482958">(Jul 09 2021 at 18:53)</a>:</h4>
<p>I'm not sure I would go that far, though this does seem to be hitting the same "owned"/Deref weirdness as before. I guess to be consistent with coercions in expressions (at the expense of no longer being consistent with references themselves) then it should match as <code>a: String</code>, and then use <code>ref</code>/<code>ref mut</code> mode if you are matching on a <code>&amp;Vec</code> or <code>&amp;mut Vec</code>.</p>
<p>However, unlike expressions, you can't just insert a &amp; or &amp;mut to guide the coercion...</p>



<a name="245499550"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245499550" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245499550">(Jul 09 2021 at 21:10)</a>:</h4>
<blockquote>
<p>I don't believe this is the case, at least not syntactically- * doesn't operate on &amp;Ts but on Ts, and it converts to &lt;T as Deref&gt;::Target without the extra &amp;. For example given s: String, *s: str.</p>
</blockquote>
<p>Yeah I think my explanation was terrible and at least a little wrong. <code>*x</code> expands to <code>*Deref::deref(&amp;x)</code> if <code>x</code> isn't a reference.</p>



<a name="245499908"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245499908" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245499908">(Jul 09 2021 at 21:12)</a>:</h4>
<blockquote>
<p>Hmm, seems ambiguous to me: should matching Vec&lt;String&gt; against [a, b] match as a: &amp;String, a: &amp;mut String, or, when Vec&lt;T&gt;: DerefMove, match as a: String?</p>
</blockquote>
<p>I think this would follow the same rules as the match ergonomics binding modes, i.e., it depends on the structure of the type and how the matched variables are used</p>



<a name="245509935"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245509935" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245509935">(Jul 09 2021 at 22:04)</a>:</h4>
<p>One issue with the scheme I <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax/near/245388290">mentioned</a> earlier for determining the binding mode through a deref is that it means that matching vectors uses ref mut binding mode, so you get this:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">match</span><span class="w"> </span><span class="p">(</span><span class="n">vec</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: &amp;mut String</span>
<span class="w">    </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>This is okay I guess, it makes sense from the signature of the deref impl, but importantly it is future incompatible with adding DerefMove to <code>Vec&lt;T&gt;</code>, since then <code>a</code> would get type <code>a: String</code> and any code that assumes it's a reference would break (and the match would also start consuming the vec which could also break subsequent uses). I would like this to only happen when there has been some positive indication that a DerefMut/DerefMove impl will not be added later.</p>



<a name="245510460"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245510460" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245510460">(Jul 09 2021 at 22:07)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256841">Nick Cameron</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax/near/245499908">said</a>:</p>
<blockquote>
<blockquote>
<p>Hmm, seems ambiguous to me: should matching Vec&lt;String&gt; against [a, b] match as a: &amp;String, a: &amp;mut String, or, when Vec&lt;T&gt;: DerefMove, match as a: String?</p>
</blockquote>
<p>I think this would follow the same rules as the match ergonomics binding modes, i.e., it depends on the structure of the type and how the matched variables are used</p>
</blockquote>
<p>sounds good as long as the matching doesn't decide which mode to use based on if types implement <code>DerefMut</code> or <code>DerefMove</code>. erroring after deciding which mode to use due to a missing impl is fine, just don't change type deduction based on a type deciding to also impl <code>DerefMut</code> or <code>DerefMove</code></p>



<a name="245511091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245511091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245511091">(Jul 09 2021 at 22:11)</a>:</h4>
<p>I think now that use of the deref operator in a pattern, implicitly or explicitly, should <em>not</em> change the default binding mode. Instead you just get an error if you try to move through a Deref/DerefMut or ref-mut bind through a Deref. That will produce much saner errors, and give people the tools to do something about the binding mode change. You will still get default ref binding mode if you match on a reference, so the same trick as today will work in the presence of deref patterns.</p>



<a name="245511348"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245511348" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245511348">(Jul 09 2021 at 22:13)</a>:</h4>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">match</span><span class="w"> </span><span class="p">(</span><span class="n">vec</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="o">*</span><span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: String, move error</span>
<span class="w">  </span><span class="o">*</span><span class="p">[</span><span class="k">ref</span><span class="w"> </span><span class="n">a</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: &amp;String, okay</span>
<span class="w">  </span><span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: String, move error</span>
<span class="w">  </span><span class="p">[</span><span class="o">*</span><span class="n">a</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: str, unsized local</span>
<span class="w">  </span><span class="p">[</span><span class="o">*</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">a</span><span class="p">)]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: &amp;str, okay</span>
<span class="p">}</span><span class="w"></span>
<span class="k">match</span><span class="w"> </span><span class="p">(</span><span class="n">vecref</span>: <span class="kp">&amp;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="o">&amp;*</span><span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: String, move error</span>
<span class="w">  </span><span class="o">&amp;</span><span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: String, move error</span>
<span class="w">  </span><span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: &amp;String, okay</span>
<span class="w">  </span><span class="p">[</span><span class="o">*</span><span class="n">a</span><span class="p">]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: &amp;str, okay</span>
<span class="w">  </span><span class="p">[</span><span class="o">*</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">a</span><span class="p">)]</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// a: &amp;str, same thing</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="245512308"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%20Syntax/near/245512308" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.20Syntax.html#245512308">(Jul 09 2021 at 22:18)</a>:</h4>
<p>Note that using <code>*pat</code> on the <code>&amp;Vec&lt;String&gt;</code> will check <code>pat</code> at <code>Vec&lt;String&gt;</code> without a binding mode change, which is exactly what <code>&amp;pat</code> would do in the same context, so this does give some evidence that maybe we don't need two operators for this and can reuse <code>&amp;</code> for deref</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>